package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.heima.article.dto.ArticleDto;
import com.heima.article.feign.ArticleFeign;
import com.heima.common.aliyun.service.AliyunGreenService;
import com.heima.common.dto.ResponseResult;
import com.heima.common.enums.MediaEnum;
import com.heima.common.minio.service.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ContentDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.service.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AuditServiceImpl implements IAuditService {
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    private IWmNewsService wmNewsService;
    @Autowired
    private IWmUserService wmUserService;
    @Autowired
    private IWmChannelService wmChannelService;
    @Autowired
    private AliyunGreenService greenService;
    @Autowired
    private MinIOService minIOService;
    @Autowired
    private IWmSensitiveService sensitiveService;
    //            0 草稿
    //            1 提交（待审核）
    //            2 审核失败
    //            3 人工审核
    //            4 人工审核通过
    //            8 审核通过（待发布）
    //            9 已发布
    @Override
    @Async("leadnewsExecutor")
    public void audit(WmNews wmNews) {

        if (wmNews.getStatus()==9) {
            return;
        }
        //4 人工审核通过              8 审核通过（待发布）
        if(wmNews.getStatus()==4||wmNews.getStatus()==8){
            if (wmNews.getPublishTime().getTime()<=new Date().getTime()) {
                saveArticle(wmNews);
                return;
            }
        }
        //            1 提交（待审核）
        if(wmNews.getStatus()==1){

            Map<String, Object> textAndImageFromContent = getTextAndImageFromContent(wmNews.getContent());
            String text = (String) textAndImageFromContent.get("text");

            List<String> contentImageList = (List<String>) textAndImageFromContent.get("image");
            List<String> allImages = new ArrayList<>();
            try {
                // 自管理敏感词过滤
                boolean sensitiveResult = checkSensitive(text, wmNews);
                if (!sensitiveResult) {
                    return;
                }
                boolean textFlag = checkText(text, wmNews);
                if(!textFlag){
                    return;
                }
                if(ObjectUtils.isNotEmpty(contentImageList)){
                    allImages.addAll(contentImageList);
                }
                String frontImages = wmNews.getImages();
                List<String> frontImageList = Arrays.asList(frontImages.split(","));
                if (ObjectUtils.isNotEmpty(frontImageList)) {
                    allImages.addAll(frontImageList);
                }

                boolean imageFlag = checkImage(allImages, wmNews);
                if(!imageFlag){
                    return;
                }
                if(wmNews.getPublishTime().getTime()<=new Date().getTime()){
                    wmNews.setEnable(true);
                    saveArticle(wmNews);
                }else {
                    wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_PASS.getVal());
                    wmNewsService.updateById(wmNews);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 直接拷贝：检查传入的文本是否包含敏感词
     *
     * @param text   文本
     * @param wmNews 自媒体用户发布的文章
     * @return
     */
    private boolean checkSensitive(String text, WmNews wmNews) {
        boolean result = false;
        //1.判断敏感词工具中的map是否为空，如果为空，从数据库中加载敏感词到Map中
        if (CollectionUtils.isEmpty(SensitiveWordUtil.dictionaryMap)) {
            LambdaQueryWrapper<WmSensitive> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(WmSensitive::getSensitives);
            //1.1 查询敏感词表中名称列
            List<WmSensitive> sensitiveList = sensitiveService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(sensitiveList)) {
                List<String> collect = sensitiveList.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
                //1.2 初始化敏感词map
                SensitiveWordUtil.initMap(collect);
            }
        }
        //2. 审核标题
        Map<String, Integer> mapTitle = SensitiveWordUtil.matchWords(wmNews.getTitle());
        if (mapTitle.size() <= 0) {
            //2.1 文章标题审核通过
            //2.1.1 继续审核文章内容是否包含敏感词
            Map<String, Integer> mapContent = SensitiveWordUtil.matchWords(text);
            if (CollectionUtils.isEmpty(mapContent)) {
                //内容审核不包含敏感词
                result = true;
            } else {
                //2.1.3 内容审核失败
                wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_FAIL.getVal());
                Set<String> keySet = mapContent.keySet();
                String join = String.join(",", keySet);
                wmNews.setReason("内容中包含敏感词：" + join);
                wmNewsService.updateById(wmNews);
            }
        } else {
            //2.2 文章标题审核失败
            wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_FAIL.getVal());
            Set<String> keySet = mapTitle.keySet();
            String join = String.join(",", keySet);
            wmNews.setReason("标题中包含敏感词：" + join);
            wmNewsService.updateById(wmNews);
            return false;
        }
        return result;
    }

    private boolean checkImage(List<String> allImages, WmNews wmNews) {
        try {
            if(allImages.size()<=0){
                return true;
            }
            ArrayList<byte[]> images = new ArrayList<>();
            for (String allImage : allImages) {
                InputStream inputStream = minIOService.download(allImage);
                byte[] bytes = IOUtils.toByteArray(inputStream);
                images.add(bytes);
            }
            Map imageScan = greenService.imageScan(images);
            String suggestion = (String) imageScan.get("suggestion");
            if("pass".equals(suggestion)){
                return true;
            }
            if("review".equals(suggestion)){
                wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_ARTIFICIAL.getVal());
                wmNewsService.updateById(wmNews);
            }
            if ("block".equals(suggestion)){
                wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_FAIL.getVal());
                String label = (String) imageScan.get("label");
                String reason="阿里云审核失败，原因是："+label;
                wmNews.setReason(reason);
                wmNewsService.updateById(wmNews);
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    private boolean checkText(String text, WmNews wmNews) throws Exception {
        Map<String,String> greenTextScan = greenService.greenTextScan(text);
        String suggestion = greenTextScan.get("suggestion");
        if("pass".equals(suggestion)){
            return true;
        }
        if("review".equals(suggestion)){
            wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_ARTIFICIAL.getVal());
            wmNewsService.updateById(wmNews);
        }
        if ("block".equals(suggestion)){
            wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_FAIL.getVal());
            String label = greenTextScan.get("label");
            String reason="阿里云审核失败，原因是："+label;
            wmNews.setReason(reason);
            wmNewsService.updateById(wmNews);
        }
        return false;
    }

    /**
     * 直接拷贝 从正文中获取图片 文本
     *
     * @param content
     * @return
     */
    private Map<String, Object> getTextAndImageFromContent(String content) {
        //0.定义文本结果
        StringBuilder stringBuilder = new StringBuilder();
        //0.1 定义图片集合
        List<String> images = new ArrayList<>();
        Map<String, Object> mapResult = new HashMap<>();
        //1.将内容转为JSON数组
        List<ContentDto> contentDtos = JSON.parseArray(content, ContentDto.class);
        //2.遍历数组对象 获取文本以及图片
        for (ContentDto dto : contentDtos) {
            if ("text".equals(dto.getType())) {
                stringBuilder.append(dto.getValue());
            } else {
                images.add(dto.getValue());
            }
        }
        mapResult.put("text", stringBuilder.toString());
        mapResult.put("images", images);
        return mapResult;
    }
    private void saveArticle(WmNews wmNews) {

        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        articleDto.setId(wmNews.getArticleId());
        Integer userId = wmNews.getUserId();
        LambdaQueryWrapper<WmUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmUser::getId,userId);
        WmUser wmUser = wmUserService.getOne(queryWrapper);
        articleDto.setAuthorId(wmUser.getApAuthorId());
        articleDto.setAuthorName(wmUser.getName());
        WmChannel wmChannel = wmChannelService.getById(wmNews.getChannelId());
        articleDto.setChannelName(wmChannel.getName());
        articleDto.setLayout(wmNews.getType());
        articleDto.setFlag(0);
        articleDto.setIsDown(!wmNews.getEnable());
        ResponseResult<Long> responseResult = articleFeign.saveArticle(articleDto);
        Long articleId = responseResult.getData();
        wmNews.setArticleId(articleId);
        wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_PUBLISH.getVal());
        wmNewsService.updateById(wmNews);
    }
}
